package com.example.movie.ui.video.adapter

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.*
import androidx.navigation.findNavController
import androidx.viewpager.widget.PagerAdapter
import com.bumptech.glide.Glide
import com.example.movie.R
import com.example.movie.common.constants.AppConstants
import com.example.movie.common.constants.RequestCode
import com.example.movie.common.dsl.afterTextChanged
import com.example.movie.common.view.commentView.CommentView
import com.example.movie.common.view.commentView.callback.CustomCommentItemCallback
import com.example.movie.common.view.commentView.callback.OnCommentLoadMoreCallback
import com.example.movie.common.view.commentView.callback.OnItemClickCallback
import com.example.movie.common.view.commentView.callback.OnReplyLoadMoreCallback
import com.example.movie.common.view.commentView.defaults.DefaultCommentHolder
import com.example.movie.common.view.commentView.defaults.DefaultCommentModel
import com.example.movie.common.view.commentView.defaults.DefaultReplyHolder
import com.example.movie.common.view.commentView.utils.ViewUtil
import com.example.movie.data.movie.model.MyComment
import com.example.movie.data.movie.model.MyReply
import com.example.movie.data.user.login.model.LoggedInUserView
import com.example.movie.data.user.login.model.SharedLoginViewModel
import com.example.movie.data.video.model.VideoViewModel
import com.example.movie.ui.movie.MovieDetailActivity
import com.example.movie.ui.movie.fragment.CommentFragment
import com.example.movie.ui.user.auth.LoginActivity
import com.example.movie.ui.video.VideoFragment
import com.example.movie.ui.video.bean.VideoVo
import com.example.movie.ui.video.view.VideoView
import com.example.movie.utils.DateUtil
import com.example.movie.utils.SizeUtil
import com.example.movie.utils.cache.PreloadManager
import com.qmuiteam.qmui.layout.IQMUILayout
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton
import kotlinx.android.synthetic.main.fragment_comment.*
import kotlinx.android.synthetic.main.item_video.view.*
import kotlinx.android.synthetic.main.item_video.view.container
import kotlinx.android.synthetic.main.layout_tiktok_controller.view.*
import kotlinx.android.synthetic.main.layout_video_comment.view.*
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.properties.Delegates


class VideoAdapter(
//    private val mVideoBeans: List<VideoBean>?,
    private val mVideoBeans: List<VideoVo>?,
    private val vvm: VideoViewModel,
    private val loginViewModel: SharedLoginViewModel,
    private val videoFragment: VideoFragment,
) : PagerAdapter() {

    /**
     * View缓存池，从ViewPager中移除的item将会存到这里面，用来复用
     */
    private val mViewCachePool = mutableListOf<View>()

    private val pw = PopupWindow(videoFragment.requireContext())

    /**
     * 视频评论布局
     */
    private var commentLayout: View = LayoutInflater.from(videoFragment.requireContext())
        .inflate(R.layout.layout_video_comment, null, false)


    override fun getCount(): Int {
        return mVideoBeans?.size ?: 0
    }

    override fun isViewFromObject(view: View, o: Any): Boolean {
        return view === o
    }

    @SuppressLint("SetTextI18n")
    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val context = container.context
        var view: View? = null
        if (mViewCachePool.size > 0) { //取第一个进行复用
            view = mViewCachePool[0]
            mViewCachePool.removeAt(0)
        }
        val viewHolder: ViewHolder
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.item_video, container, false)
            viewHolder = ViewHolder(view)
        } else {
            viewHolder = view.tag as ViewHolder
        }
        val item = mVideoBeans!![position]
        //开始预加载
        PreloadManager.getInstance(context)!!.addPreloadTask(item.url, position)

        Glide
            .with(context)
            .load(AppConstants.STATIC_SOURCE_URL + item.coverImage)
            .error(R.drawable.error)
            .placeholder(R.mipmap.logo)
            .into(viewHolder.mThumb)
        viewHolder.mTitle.text = item.description

        Glide
            .with(context)
            .load(AppConstants.STATIC_SOURCE_URL + item.cimg)
            .error(R.drawable.error)
            .placeholder(R.mipmap.logo)
            .into(viewHolder.movieImage)
        viewHolder.movieName.text = item.movieName
        viewHolder.movieLikeCount.text = item.hopeLook.toString()
        viewHolder.userName.text = "@${item.userName}"
        viewHolder.likeCount.text = item.likecount.toString()
        viewHolder.commentCount.text = item.commentCount.toString()

        viewHolder.movieContainer.setOnClickListener {
            with(Bundle()) {
                putInt("movieId", item.movieid)
                val intent = Intent(it.context, MovieDetailActivity::class.java)
                intent.putExtras(this)
                it.context.startActivity(intent)
            }
        }

        Glide
            .with(context)
            .load(AppConstants.STATIC_SOURCE_URL + item.headimg)
            .error(R.drawable.error)
            .placeholder(R.mipmap.logo)
            .into(viewHolder.userHead)

        viewHolder.mTitle.setOnClickListener { v: View? ->
            Toast.makeText(
                context,
                "点击了标题",
                Toast.LENGTH_SHORT
            ).show()
        }

        viewHolder.attention.setOnClickListener {
            Toast.makeText(context, "点击关注", Toast.LENGTH_SHORT).show()
        }

        //判断用户之前是否已经点赞
        if (item.likeThisVideo) {
            viewHolder.like.setImageResource(R.drawable.heart_red)
            viewHolder.isLike = true
        } else {
            viewHolder.like.setImageResource(R.drawable.heart_white)
            viewHolder.isLike = false
        }

        viewHolder.like.setOnClickListener {
            vvm.like(item.vid)
            if (!viewHolder.isLike) {
                viewHolder.like.setImageResource(R.drawable.heart_red)
                viewHolder.isLike = true
            } else {
                viewHolder.like.setImageResource(R.drawable.heart_white)
                viewHolder.isLike = false
            }
        }

        viewHolder.showComment.setOnClickListener {
            commentLayout.apply {
                //todo 设置空白区域透明效果
//            val popWindowSkin =
//                QMUIResHelper.getAttrDrawable(context, R.attr.popupWindowStyle)
//            videoCommentLayout.blank_area.background = popWindowSkin

                //TODO 每次加载评论时都对其进行重,想要对view进行复用，但是复用出现点问题，有时间研究下
//                commentView.reset(context)

                val oldCommentView = (commentLayout as LinearLayout).getChildAt(3)
                val lp = oldCommentView.layoutParams
                (commentLayout as LinearLayout).removeViewAt(3)
                val cv = CommentView(context)
                cv.id = R.id.commentView
                cv.layoutParams = lp
                cv.background = oldCommentView.background
                (commentLayout as LinearLayout).addView(cv,3)

                //设置评论头圆角
                comment_head.setRadius(
                    SizeUtil.dip2px(context, 10f),
                    IQMUILayout.HIDE_RADIUS_SIDE_BOTTOM
                )

                close.setOnClickListener {
                    pw.dismiss()
                }
                blank_area.setOnClickListener {
                    pw.dismiss()
                }

                forumNumber.text = "评论(${viewHolder.commentCount.text})"

                initCommentView(this, context, position)
            }
            //使得pw可输入
            pw.isFocusable = true
            pw.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN
            pw.contentView = commentLayout
            pw.width = ViewGroup.LayoutParams.MATCH_PARENT
            pw.height = ViewGroup.LayoutParams.MATCH_PARENT
            pw.showAsDropDown(it, 0, 0, Gravity.BOTTOM)

            pw.setOnDismissListener {
                Log.i("test", "popupWindow dismiss")
            }

        }

        viewHolder.shareBtn.setOnClickListener {
            Toast.makeText(context, "点击了分享", Toast.LENGTH_SHORT).show()
        }

        viewHolder.buyTicket.setOnClickListener {
            it.findNavController().navigate(R.id.action_navigation_video_to_navigation_cinema)
        }

        viewHolder.mPosition = position
        container.addView(view)
        return view!!
    }

    init {
        commentLayout.apply {
            vvm.addReplyState.observe(videoFragment) {
                tempReply.id = it.toLong()
                val parent = commentView.commentList[onClickGroupPos] as MyComment
                if (parent.getReplies() == null) {
                    parent.setReplies(mutableListOf())
                }
                //todo 添加回复之后要重新设置分页属性
                commentView.addReply(tempReply, onClickGroupPos)
                input.hint = " 说点什么吧"
                refreshInput(input, "回复成功")
            }

            vvm.addCommentState.observe(videoFragment) {
                tempComment.id = it.toLong()
                commentView.addComment(tempComment)
                refreshInput(input, "评论成功")
            }

            vvm.approveState.observe(videoFragment) {
                val commentHolder = commentHolderMap[it.forumId]!!
                if (it.hasApprove) {
                    if (commentHolder is DefaultCommentHolder) {
                        (commentView.commentList[onClickGroupPos] as MyComment).isLike = true
                        (commentView.commentList[onClickGroupPos] as MyComment).prizes++
                    } else {
                        (commentView.commentList[onClickGroupPos].getReplies<MyReply>()[onClickChildPos] as MyReply).isLike =
                            true
                        (commentView.commentList[onClickGroupPos].getReplies<MyReply>()[onClickChildPos] as MyReply).prizes++
                    }

                    commentHolder.prizes.text =
                        commentHolder.prizes.text.toString().toInt().inc().toString()
                    commentHolder.prize.setImageResource(R.drawable.comment_approve)
                } else {
                    if (commentHolder is DefaultCommentHolder) {
                        (commentView.commentList[onClickGroupPos] as MyComment).isLike = false
                        (commentView.commentList[onClickGroupPos] as MyComment).prizes--
                    } else {
                        (commentView.commentList[onClickGroupPos].getReplies<MyReply>()[onClickChildPos] as MyReply).isLike =
                            false
                        (commentView.commentList[onClickGroupPos].getReplies<MyReply>()[onClickChildPos] as MyReply).prizes--
                    }

                    commentHolder.prizes.text =
                        commentHolder.prizes.text.toString().toInt().dec().toString()
                    commentHolder.prize.setImageResource(R.drawable.pxjh)
                }
            }

            vvm.commentList.observe(videoFragment) { it ->
                it?.let {
                    val commentModel = DefaultCommentModel()
                    val comments = mutableListOf<DefaultCommentModel.Comment>()
                    it.data?.let { data ->
                        repeat(data.size) { idx ->
                            val comment = MyComment()
                            data[idx].apply {
                                comment.id = forumId.toLong()
                                comment.headImg = headImg
                                comment.posterName = userName
                                comment.comment = remark
                                comment.prizes = countNumber.toInt()
                                comment.isLike = hasApprove
                                comment.date =
                                    DateUtil.parseDate(forumDate!!, "yyyy-MM-dd hh:mm:ss")

                                //初始化回复的总数据量和分页数目
                                comment.totalPages =
                                    ((replySize + defaultReplyPageSize - 1) / defaultReplyPageSize)
                                //一开始不展示，点击展开更多回复才加载回复
                                comment.totalDataSize = replySize
                                comment.currentPage = 0
                                comment.nextPage = comment.currentPage + 1
                            }
                            comments.add(comment)
                        }
                    }

                    commentModel.totalPages =
                        ((it.recordsTotal!! + defaultPageSize - 1) / defaultPageSize).toInt()
                    commentModel.currentPage = currentPage
                    commentModel.nextPage = currentPage + 1
                    commentModel.comments = comments

                    when {
                        hasInitCommentData -> {
                            commentView.loadMoreComplete(commentModel)
                        }
                        isRefreshing -> {
                            commentView.refreshComplete(commentModel)
                            isRefreshing = false
                            initCommentsSuccess()
                        }
                        else -> {
                            commentView.loadComplete(commentModel)
                            initCommentsSuccess()
                        }
                    }
                }
            }

            vvm.replyList.observe(videoFragment) { it ->
                it.success?.let { it ->
                    val replyModel = DefaultCommentModel()
                    val replies = mutableListOf<MyReply>()
                    it.data?.let {
                        for (forumVo in it) {
                            val reply = MyReply()
                            forumVo.apply {
                                reply.headImg = headImg
                                reply.date = DateUtil.parseDate(forumDate!!, "yyyy-MM-dd hh:mm:ss")
                                reply.id = forumId.toLong()
                                reply.phoneNumber = fromId
                                reply.prizes = countNumber.toInt()
                                reply.reply = remark
                                reply.replierName = userName
                                reply.isLike = hasApprove
                                reply.pid = pid.toLong()
                                reply.toName = toName
                                reply.toId = toId
                            }
                            replies.add(reply)
                        }
                    }
                    val tmp = mutableListOf(MyComment())
                    // todo 输入分页和数据量等信息
                    tmp[0].replies = replies as List<DefaultCommentModel.Comment.Reply>?
                    replyModel.comments = tmp as List<DefaultCommentModel.Comment>?

                    commentView.loadMoreReplyComplete(replyModel);
                }
            }
        }

    }


    private fun initCommentView(
        commentLayout: View,
        context: Context,
        position: Int
    ) {
        commentLayout.apply {
            refreshCommentState()
            loadData(position)

            val emptyCommentLayout =
                LayoutInflater.from(context).inflate(R.layout.layout_comment_empty, null, false)
            commentView.setEmptyView(emptyCommentLayout)
            commentView.setViewStyleConfigurator(CommentFragment.CustomStyleConfig(context))

            commentView
                .from(context)
                .callbackBuilder()
                .setOnScrollCallback(null)
                .setOnCommentLoadMoreCallback(object : OnCommentLoadMoreCallback {
                    override fun loading(
                        currentPage: Int,
                        willLoadPage: Int,
                        isLoadedAllPages: Boolean
                    ) {
                        if (isLoadedAllPages) {
                            return
                        }
                        vvm.loadForumPage(
                            mVideoBeans!![position].vid,
                            willLoadPage,
                            defaultPageSize
                        )
                        CommentSate.currentPage = willLoadPage
                    }

                    override fun complete() {
                    }

                    override fun failure(msg: String?) {
                    }

                })
                .setOnReplyLoadMoreCallback(object : OnReplyLoadMoreCallback<MyReply> {

                    override fun loading(reply: MyReply?, willLoadPage: Int) {
                        vvm.loadReplies(
                            reply!!.getPid(),
                            willLoadPage,
                            defaultReplyPageSize
                        )
                    }

                    override fun complete() {
                    }

                    override fun failure(msg: String?) {
                    }

                })
                .setOnItemClickCallback(object :
                    OnItemClickCallback<MyComment, DefaultCommentModel.Comment.Reply> {

                    override fun commentItemOnClick(
                        position: Int,
                        comment: MyComment?,
                        view: View?
                    ) {
                        if (!loginViewModel.isLoggedIn()) {
                            videoFragment.requireActivity().startActivityForResult(
                                Intent(context, LoginActivity::class.java),
                                RequestCode.NEED_LOGIN
                            )
                            return
                        }
                        onClickGroupPos = position
                        input.hint = "回复@${comment?.posterName}"
                        requestInput(this@apply)
                        pid = comment!!.id.toInt()
                    }

                    override fun replyItemOnClick(
                        c_position: Int,
                        r_position: Int,
                        reply: DefaultCommentModel.Comment.Reply?,
                        view: View?
                    ) {
                        val r = reply as MyReply
                        onClickChildPos = c_position
                        input.hint = "回复@${r.replierName}"
                        requestInput(this@apply)
                        isChildReply = true
                        toName = r.replierName
                        toId = r.phoneNumber
                        pid = reply.pid.toInt()
                    }

                })
                .customCommentItem(CustomCommentItemCallback<MyComment> { groupPosition, comment, inflater, convertView, parent ->
                    val myCommentHolder: DefaultCommentHolder
                    var view: View? = convertView
                    if (view == null) {
                        view = inflater.inflate(R.layout.item_comment, parent, false)
                        myCommentHolder = DefaultCommentHolder(view)
                        view.tag = myCommentHolder
                    } else {
                        myCommentHolder = view.tag as DefaultCommentHolder
                    }

                    val tmp = comment as MyComment
                    commentHolderMap[comment.id.toInt()] = myCommentHolder

                    myCommentHolder.posterName.text = tmp.posterName
                    myCommentHolder.content.text = tmp.comment
                    myCommentHolder.time.text = ViewUtil.getTime(tmp.date)
                    Glide
                        .with(context)
                        .load(AppConstants.STATIC_SOURCE_URL + tmp.headImg)
                        .placeholder(R.mipmap.logo)
                        .error(R.drawable.error)
                        .into(myCommentHolder.ico)
                    myCommentHolder.prizes.text = tmp.prizes.toString()

                    myCommentHolder.prize.setOnClickListener {
                        onClickGroupPos = groupPosition
                        vvm.approve(tmp.id.toInt())
                    }

                    //该用户已点赞该条评论
                    if (tmp.isLike) {
                        myCommentHolder.prize.setImageResource(R.drawable.comment_approve)
                    } else {
                        myCommentHolder.prize.setImageResource(R.drawable.pxjh)
                    }

                    return@CustomCommentItemCallback view

                })
                .customReplyItem { groupPosition, childPosition, isLastReply, reply, inflater, convertView, parent ->
                    val myReplyHolder: DefaultReplyHolder
                    var view: View? = convertView
                    if (view == null) {
                        //covertView用于view的复用，如果为空才重新创建视图
                        view = inflater.inflate(R.layout.item_reply, parent, false)
                        myReplyHolder = DefaultReplyHolder(view)
                        view!!.tag = myReplyHolder
                    } else {
                        myReplyHolder = view!!.tag as DefaultReplyHolder
                    }
                    val tmp = reply as MyReply
                    commentHolderMap[reply.id.toInt()] = myReplyHolder

                    if (tmp.toName != null) {
                        myReplyHolder.replierName.text = "${tmp.replierName} ▶ ${tmp.toName}"
                    } else {
                        myReplyHolder.replierName.text = tmp.replierName
                    }
                    myReplyHolder.content.text = tmp.reply
                    myReplyHolder.time.text = ViewUtil.getTime(tmp.getDate())
                    Glide
                        .with(context)
                        .load(AppConstants.STATIC_SOURCE_URL + tmp.headImg)
                        .placeholder(R.mipmap.logo)
                        .error(R.drawable.error)
                        .into(myReplyHolder.ico)
                    myReplyHolder.prizes.text = tmp.prizes.toString()
                    myReplyHolder.prize.setOnClickListener {
                        onClickGroupPos = groupPosition
                        onClickChildPos = childPosition
                        vvm.approve(tmp.id.toInt())
                    }
                    if (tmp.isLike) {
                        myReplyHolder.prize.setImageResource(R.drawable.comment_approve)
                    } else {
                        myReplyHolder.prize.setImageResource(R.drawable.pxjh)
                    }

                    return@customReplyItem view

                }
                .buildCallback()

            input.afterTextChanged {
                send_btn.isEnabled = it.isNotBlank()
            }

            send_btn.setOnClickListener {
                sendMessage(this, position)
            }
        }

    }


    private fun initCommentsSuccess() {
        hasInitCommentData = true
    }

    private fun refreshInput(input: EditText, tip: String) {
        input.setText("")
        val successTipDialog = QMUITipDialog.Builder(videoFragment.requireContext())
            .setIconType(QMUITipDialog.Builder.ICON_TYPE_SUCCESS)
            .setTipWord(tip)
            .create()
        successTipDialog.show()
        Handler(Looper.myLooper()!!).postDelayed({
            successTipDialog.dismiss()
        }, TimeUnit.SECONDS.toMillis(1))
    }

    private fun loadData(position: Int) {
        vvm.loadForumPage(mVideoBeans!![position].vid, currentPage, defaultPageSize)
    }

    private fun requestInput(layout: View) {
        layout.input.requestFocus()
        val inputMethodService =
            videoFragment.requireActivity()
                .getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodService.showSoftInput(layout.input, InputMethodManager.SHOW_IMPLICIT)
    }

    private fun sendMessage(layout: View, position: Int) {
        val content = layout.input.text.toString()
        val user = getCurrentUser()
        if (pid == 0) {
            //构建临时评论实体
            tempComment = MyComment()
            tempComment.headImg = user.headImg
            tempComment.posterName = user.nickName
            tempComment.date = Date().time
            tempComment.comment = content
            tempComment.prizes = 0
        } else {
            tempReply = MyReply()
            tempReply.reply = content
            tempReply.headImg = user.headImg
            tempReply.toName = toName
            tempReply.toId = toId
            tempReply.replierName = user.nickName
            tempReply.phoneNumber = user.phoneNumber
            tempReply.date = Date().time
            tempReply.prizes = 0
            tempReply.pid = pid.toLong()
        }
        vvm.addForum(mVideoBeans!![position].vid, content, pid, toId)
        refreshSelectState()
    }

    private fun getCurrentUser(): LoggedInUserView {
        return loginViewModel.loginResult.value?.success!!
    }

    private fun refreshSelectState() {
        pid = 0
        toName = null
        toId = null
        isChildReply = false
    }


    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
        val itemView = `object` as View
        container.removeView(itemView)
        val item = mVideoBeans!![position]
        //取消预加载
        PreloadManager.getInstance(container.context)!!.removePreloadTask(item.url)
        //保存起来用来复用
        mViewCachePool.add(itemView)
    }

    /**
     * 借鉴ListView item复用方法
     */
    class ViewHolder internal constructor(itemView: View) {
        var mPosition = 0

        var movieImage = itemView.video_movie_img
        var movieName = itemView.movie_name
        var movieLikeCount = itemView.movie_like_count
        var userName = itemView.username
        var userHead = itemView.user_head
        var likeCount = itemView.like_count
        var commentCount = itemView.comment_count
        var shareCount = itemView.share_count
        var movieContainer = itemView.movie_container
        var attention = itemView.attention

        var mTitle: TextView

        //封面图
        var mThumb: ImageView
        var mVideoView: VideoView = itemView.video_View
        var mPlayerContainer: FrameLayout
        var like: ImageView
        var showComment: ImageView
        var shareBtn: ImageView
        var buyTicket: QMUIRoundButton
        var isLike = false

        init {
            mThumb = mVideoView.iv_thumb
            mPlayerContainer = itemView.container
            mTitle = itemView.title
            like = itemView.video_approve
            showComment = itemView.comment
            shareBtn = itemView.share
            buyTicket = itemView.video_buy_ticket
            itemView.tag = this
        }
    }

    private fun refreshCommentState() {
        hasInitCommentData = false
        currentPage = 1
        isRefreshing = false
        commentHolderMap.clear()
        isChildReply = false
        toName = null
        toId = null
        pid = 0
    }

    companion object CommentSate {
        /**
         * 评论相关状态
         */
        var hasInitCommentData = false
        const val defaultPageSize = 10
        var currentPage = 1
        var isRefreshing = false
        var onClickGroupPos by Delegates.notNull<Int>()
        var onClickChildPos by Delegates.notNull<Int>()

        /**
         * key应该使用id来标识，而不是位置，避免极端情况下发生错误
         */
        val commentHolderMap =
            mutableMapOf<Int, com.example.movie.common.view.commentView.view.ViewHolder>()

        /**
         * 回复相关状态
         */
        const val defaultReplyPageSize = 5
        var isChildReply = false
        var toName: String? = null
        var toId: String? = null

        /**
         * 选择的顶级评论id,标识动作是评论还是回复
         */
        var pid = 0

        /**
         * 临时存储的恢复实体，当服务器确认恢复成功随即将恢复添加在ui中
         */
        lateinit var tempReply: MyReply
        lateinit var tempComment: MyComment
    }


}